/*
 * SampleApp.java
 * Companion code to article Introduction to Facebook SDK for Android.
 * Shows how to use the Facebook SDK for Android.
 *
 * Author: C. Enrique Ortiz | http://cenriqueortiz.com
 * Copyright 2010 C. Enrique Ortiz.
 * Based in part on example from Facebook Android SDK
 * Copyright 2010 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.cenriqueortiz.facebook;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Window;
import android.widget.ListView;
import android.widget.TextView;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.AsyncFacebookRunner.RequestListener;
import com.facebook.android.DialogError;
import com.facebook.android.Facebook;
import com.facebook.android.FacebookError;
import com.facebook.android.R;
import com.facebook.android.Util;

/**
 * Sample App Activity
 * @author http://CEnriqueOrtiz.com
 */
public class SampleApp extends Activity {

    // Set Application ID to your registered app client_id
    // See http://www.facebook.com/developers/createapp.php
    public static final String APP_ID = "192872734087189";

    private static final String[] PERMISSIONS =
//        new String[] {"publish_stream", "read_stream", "offline_access"};
    new String[] {"publish_stream", "read_stream", "offline_access","read_friendlists","manage_friendlists","user_work_history","friends_work_history"};
    private TextView mText;
    private Handler mHandler = new Handler();
    private ProgressDialog mSpinner;
    private final ArrayList<Friend> friends = new ArrayList<Friend>();
    private FriendsArrayAdapter friendsArrayAdapter;
    private ListView listView;
    private Facebook mFacebook;
    private AsyncFacebookRunner mAsyncRunner;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Make sure the app client_app has been set
        //@jieum test
        if (APP_ID == null) {
            Util.showAlert(this, "Warning", "Facebook Applicaton ID must be set...");
        }

        // Initialize the content view
        setContentView(R.layout.main);
        // Get the status text line resource
        mText = (TextView) SampleApp.this.findViewById(R.id.txt);

        // Setup the ListView Adapter that is loaded when selecting "get friends"
        listView = (ListView) findViewById(R.id.friendsview);
        friendsArrayAdapter = new FriendsArrayAdapter(this, R.layout.rowlayout, friends);
        listView.setAdapter(friendsArrayAdapter);
        
        // Define a spinner used when loading the friends over the network
        mSpinner = new ProgressDialog(listView.getContext());
        mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
        mSpinner.setMessage("Loading...");

        // Initialize the Facebook session
        mFacebook = new Facebook(APP_ID);
        mAsyncRunner = new AsyncFacebookRunner(mFacebook);
    }

    //////////////////////////////////////////////////////////////////////

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      Log.d("FB Sample App", "onActivityResult(): " + requestCode);
      Log.d("Facebook Sample App", "onActivityResult(): " + requestCode);
      mFacebook.authorizeCallback(requestCode, resultCode, data);
    }

    //////////////////////////////////////////////////////////////////////
    // Get Friends request listener
    //////////////////////////////////////////////////////////////////////

    /**
     * FriendsRequestListener implements a request lister/callback
     *  for "get friends" requests
     */
    public class FriendsRequestListener implements
            com.facebook.android.AsyncFacebookRunner.RequestListener {

        /**
         * Called when the request to get friends has been completed.
         * Retrieve and parse and display the JSON stream.
         */
    	@Override
        public void onComplete(final String response,Object state) {
        	Log.d("Facebook","SampleApp.onComplete..called!!!!");
            mSpinner.dismiss();
            try {
                // process the response here: executed in background thread
                Log.d("Facebook-Example-Friends Request", "response.length(): " + response.length());
                Log.d("Facebook-Example-Friends Request", "Response: " + response);

                final JSONObject json = new JSONObject(response);
                JSONArray d = json.getJSONArray("data");
                int l = (d != null ? d.length() : 0);
                Log.d("Facebook-Example-Friends Request", "d.length(): " + l);

                for (int i=0; i<l; i++) {
                    JSONObject o = d.getJSONObject(i);
                    String n = o.getString("name");
                    String id = o.getString("id");
                    Friend f = new Friend();
                    f.id = id;
                    f.name = n;
                    friends.add(f);
                }

                // Only the original owner thread can touch its views
                SampleApp.this.runOnUiThread(new Runnable() {
                    public void run() {
                        friendsArrayAdapter = new FriendsArrayAdapter(
                                SampleApp.this, R.layout.rowlayout, friends);
                        listView.setAdapter(friendsArrayAdapter);
                        friendsArrayAdapter.notifyDataSetChanged();
                    }
                });
            } catch (JSONException e) {
                Log.w("Facebook-Example", "JSON Error in response");
            }
        }

        public void onFacebookError(FacebookError e) {
            // Ignore Facebook errors
            mSpinner.dismiss();
        }

        public void onFileNotFoundException(FileNotFoundException e) {
            // Ignore File not found errors
            mSpinner.dismiss();
        }

        public void onIOException(IOException e) {
            // Ignore IO Facebook errors
            mSpinner.dismiss();
        }

        public void onMalformedURLException(MalformedURLException e) {
            // Ignore Malformed URL errors
            mSpinner.dismiss();
        }

		@Override
		public void onIOException(IOException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onFileNotFoundException(FileNotFoundException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onMalformedURLException(MalformedURLException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onFacebookError(FacebookError e, Object state) {
			// TODO Auto-generated method stub
			
		}
    }

    //////////////////////////////////////////////////////////////////////
    // Wall Post request listener
    //////////////////////////////////////////////////////////////////////

    /**
     * WallPostRequestListener implements a request lister/callback
     *  for "wall post requests"
     */
    public class WallPostRequestListener implements
            com.facebook.android.AsyncFacebookRunner.RequestListener {

        /**
         * Called when the wall post request has completed
         */
        public void onComplete(final String response) {
            Log.d("Facebook-Example", "Got response: " + response);
        }

        public void onFacebookError(FacebookError e) {
            // Ignore Facebook errors
        }

        public void onFileNotFoundException(FileNotFoundException e) {
            // Ignore File not found errors
        }

        public void onIOException(IOException e) {
            // Ignore IO Facebook errors
        }

        public void onMalformedURLException(MalformedURLException e) {
            // Ignore Malformed URL errors
        }

		@Override
		public void onComplete(String response, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onIOException(IOException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onFileNotFoundException(FileNotFoundException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onMalformedURLException(MalformedURLException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onFacebookError(FacebookError e, Object state) {
			// TODO Auto-generated method stub
			
		}

    }

    //////////////////////////////////////////////////////////////////////
    // Wall post dialog completion listener
    //////////////////////////////////////////////////////////////////////

    /**
     * WallPostDialogListener implements a dialog lister/callback
     */
    public class WallPostDialogListener implements
            com.facebook.android.Facebook.DialogListener {

        /**
         * Called when the dialog has completed successfully
         */
        public void onComplete(Bundle values) {
            final String postId = values.getString("post_id");
            if (postId != null) {
                Log.d("FB Sample App", "Dialog Success! post_id=" + postId);
                mAsyncRunner.request(postId, new WallPostRequestListener());
            } else {
                Log.d("FB Sample App", "No wall post made");
            }
        }

        @Override
        public void onCancel() {
            // No special processing if dialog has been canceled
        }

        @Override
        public void onError(DialogError e) {
            // No special processing if dialog has been canceled
        }

        @Override
        public void onFacebookError(FacebookError e) {
            // No special processing if dialog has been canceled
        }
    }

    /////////////////////////////////////////////////////////
    // Login / Logout Listeners
    /////////////////////////////////////////////////////////

    /**
     * Listener for login dialog completion status
     */
    private final class LoginDialogListener implements
            com.facebook.android.Facebook.DialogListener {

        /**
         * Called when the dialog has completed successfully
         */
        public void onComplete(Bundle values) {
            // Process onComplete
            Log.d("FB Sample App", "LoginDialogListener.onComplete()");
            // Dispatch on its own thread
            mHandler.post(new Runnable() {
                public void run() {
                    mText.setText("Facebook login successful. Press Menu...");
                }
            });
        }

        /**
         *
         */
        public void onFacebookError(FacebookError error) {
            // Process error
            Log.d("FB Sample App", "LoginDialogListener.onFacebookError()");
        }

        /**
         *
         */
        public void onError(DialogError error) {
            // Process error message
            Log.d("FB Sample App", "LoginDialogListener.onError()");
        }

        /**
         *
         */
        public void onCancel() {
            // Process cancel message
            Log.d("FB Sample App", "LoginDialogListener.onCancel()");
   }
    }

    /**
     * Listener for logout status message
     */
    private class LogoutRequestListener implements RequestListener {

        /** Called when the request completes w/o error */
        public void onComplete(String response) {

            // Only the original owner thread can touch its views
            SampleApp.this.runOnUiThread(new Runnable() {
                public void run() {
                    mText.setText("Thanks for using FB Sample App. Bye bye...");
                    friends.clear();
                    friendsArrayAdapter.notifyDataSetChanged();
                }
            });

            // Dispatch on its own thread
            mHandler.post(new Runnable() {
                public void run() {
                }
            });
        }

        public void onFacebookError(FacebookError e) {
            // Process Facebook error message
        }

        public void onFileNotFoundException(FileNotFoundException e) {
            // Process Exception
        }

        public void onIOException(IOException e) {
            // Process Exception
        }

        public void onMalformedURLException(MalformedURLException e) {
            // Process Exception
        }

		@Override
		public void onComplete(String response, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onIOException(IOException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onFileNotFoundException(FileNotFoundException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onMalformedURLException(MalformedURLException e, Object state) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void onFacebookError(FacebookError e, Object state) {
			// TODO Auto-generated method stub
			
		}

    }

    ///////////////////////////////////////////////////////////////////
    // Menu handlers
    ///////////////////////////////////////////////////////////////////

    /**
     * Invoked at the time to create the menu
     * @param menu is the menu to create
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);
        return true;
    }

    /**
     * Invoked when preparing to display the menu
     * @param menu is the menu to prepare
     */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {

        MenuItem loginItem = menu.findItem(R.id.login);
        MenuItem postItem = menu.findItem(R.id.wallpost);
        MenuItem getfriendsItem = menu.findItem(R.id.getfriends);
        if (mFacebook.isSessionValid()) {
            loginItem.setTitle("Logout");
            postItem.setEnabled(true);
            getfriendsItem.setEnabled(true);
        } else {
            loginItem.setTitle("Login");
            postItem.setEnabled(false);
            getfriendsItem.setEnabled(false);
        }
        loginItem.setEnabled(true);
        return super.onPrepareOptionsMenu(menu);
    }

    /**
     * Invoked when a menu item has been selected
     * @param item is the selected menu items
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {

            // Login/logout toggle
            case R.id.login:
                // Toggle the button state.
                //  If coming from login transition to logout.
                if (mFacebook.isSessionValid()) {
                	Log.d("Facebook","mFacebook.isSessionValid() called..");
                    AsyncFacebookRunner asyncRunner = new AsyncFacebookRunner(mFacebook);
                    asyncRunner.logout(this.getBaseContext(), new LogoutRequestListener());
                } else {
                	Log.d("Facebook","mFacebook.isSessionValid() is false.....");
                    // Toggle the button state.
                    //  If coming from logout transition to login (authorize).
                    mFacebook.authorize(this, PERMISSIONS, new LoginDialogListener());
                }
                break;

            // Wall Post
            case R.id.wallpost: // Wall Post
                mFacebook.dialog(SampleApp.this, "stream.publish", new WallPostDialogListener());
                break;

            // Get Friend's List
            case R.id.getfriends: // Wall Post
                // Get the authenticated user's friends
                mSpinner.show();
                mAsyncRunner.request("me/friends", new FriendsRequestListener());
                break;

            default:
                return false;

        }
        return true;
    }

}
